/*
 * =====================================================================================
 *
 *       Filename:  Thread.cpp
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  05/31/12 17:51:36
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author: jjlee (jz), jjlee@nhn.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <Thread.h>
#include <iostream>

#include <string.h>

using namespace std;
Thread::Thread():runnable(NULL), thread_id(0), exit_code(0)
{
	cout << "create thread: " << (unsigned long int) thread_id << endl;
}

Thread::Thread(Runnable* thread):runnable(thread), thread_id(0), exit_code(0)
{
	//cout << "create runnable with runnable interface" << endl;
}

Thread::~Thread() 
{
	//cout << "delete thread[ " << thread_id << " ]" << endl;
}

void* Thread::main(void* instance) 
{
	Thread* ptr = static_cast<Thread *> (instance);
	ptr->run();
}

void Thread::start()
{
	int ret = pthread_create(&thread_id, NULL, &Thread::main, this);
	if (ret != 0)
	{
		/* if pthread_create is failed, thread_id is undifined */
		thread_id = 0;
		cerr << "ERROR] pthread_create:" << strerror(ret)<<endl;
	}
	cerr << "pthread start:" << (unsigned long int) thread_id <<endl;
}

void Thread::yield()
{
	pthread_yield();
}

void Thread::exit(int ret)
{
	exit_code = ret;
	pthread_exit(&exit_code);
}

pthread_t Thread::getId()
{
	return pthread_self();
}

int Thread::wait()
{
	void* ptr;
	int ret = pthread_join(thread_id, &ptr);
	if (ret != 0)
	{
		cerr << "ERROR] pthread_join:" << strerror(ret)<<endl;
		return ret;
	}

	return exit_code;
}

void Thread::run()
{
	if (runnable != NULL) 
	{
		runnable->run();
	}
	 else 
	{
		cerr << "ERROR] runnable is not assign" << endl;
	}
}


